package org.example.os.synchronous.producer_comsumer;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock + Condition
 */
public class LockConditionAchievement {
    private final LinkedList<Integer> buffer = new LinkedList<>();
    private final int capacity;
    private final Lock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();

    public LockConditionAchievement(int capacity){
        this.capacity = capacity;
    }

    public void produce() throws InterruptedException {
        int value = 0;
        while (true) {
            lock.lock();
            try {
                while(buffer.size() == capacity){
                    notFull.await();
                }
                System.out.println("生产者生产:" + value);
                buffer.add(value++);
                notEmpty.signal();
            } finally {
                lock.unlock();
            }
            Thread.sleep(1000);
        }
    }

    public void consume() throws InterruptedException {
        while (true) {
            lock.lock();
            try {
                while ( buffer.isEmpty() ) {
                    notEmpty.await();
                }
                int value = buffer.removeFirst();
                System.out.println("消费者消费:" + value);
                notFull.signal();
            } finally {
                lock.unlock();
            }
            Thread.sleep(1000);
        }
    }
}
